<script setup lang='ts'>
interface Props {
  title: string
  odds: string
  cartInfo: ICartInfo
  disabled?: boolean
  size?: 'big' | 'small'
}

/**
 *
 * 赔率上涨 右上角 绿色 闪烁，赔率从上往下滚动
 * 赔率下降 右下角 红色 闪烁，赔率从下往上滚动
 */

defineOptions({ name: 'AppSportsBetButton' })
const props = withDefaults(defineProps<Props>(), {
  size: 'small',
})

const sportsStore = useSportsStore()

const betButton = ref()
const oldONum = ref('')
const saveNum = ref(props.odds)
const upDown = ref('')
const isSelected = ref(false)
let timerUpdown: any
let timerSpan: any

const listToCartData = ref<ISportListToCartData>({
  wid: props.cartInfo.wid,
  ov: props.odds,
  os: props.disabled ? 0 : 1,
  mlid: props.cartInfo.mlid,
})

const _disabled = ref(props.disabled || +listToCartData.value.ov === 0)
const isZeroOdd = computed(() => +listToCartData.value.ov === 0)
const direction = computed(() => {
  return upDown.value ? upDown.value === 'up' ? 'down' : 'up' : ''
})

function clickHandler() {
  if (isZeroOdd.value)
    return

  /** 增加kyc逻辑 */
  // if (isLogin.value && isKYCVerifyOpen.value && !isCompleteKYC.value)
  //   return openKYCDialog()

  if (sportsStore.cart.checkWid(props.cartInfo.wid)) {
    sportsStore.cart.remove(props.cartInfo.wid)
  }
  else if (_disabled.value) {
    return ''
  }
  else {
    sportsStore.cart.add(props.cartInfo)
    startDomTransition()
  }
}
function startDomTransition() {
  nextTick(() => {
    const startDom = betButton.value
    const endDom = document.getElementById('bet-slip-header-total')

    if (!startDom || !endDom)
      return

    domTransition(startDom, endDom)
  })
}

function resetUpDown() {
  clearTimeout(timerUpdown)
  timerUpdown = setTimeout(() => {
    upDown.value = ''
    clearTimeout(timerUpdown)
  }, 2000)
}
function resetOldNum() {
  clearTimeout(timerSpan)
  timerSpan = setTimeout(() => {
    oldONum.value = ''
    clearTimeout(timerSpan)
  }, 350)
}

/** 数据改变，向购物车发送数据 */
function listToCartEventEmit() {
  appEventBus.emit(EventBusNames.SPORTS_LIST_TO_CART_BUS, listToCartData.value)
}
/** 处理列表通知发送的数据 */
function eventHandler(_data: ISportListToCartData) {
  if (_data.mlid === props.cartInfo.mlid) {
    listToCartData.value.os = _data.os
    _disabled.value = _data.os === 0
    if (_data.wid === listToCartData.value.wid)
      listToCartData.value.ov = _data.ov
  }
}
/** 监听列表发送的事件 */
function addCartToListEvent() {
  appEventBus.on(EventBusNames.SPORTS_CART_TO_LIST_BUS, eventHandler)
}
/** 移除列表发送的事件 */
function removeCartToListEvent() {
  appEventBus.off(EventBusNames.SPORTS_CART_TO_LIST_BUS, eventHandler)
}

watch(() => props.odds, (newOdds: string, oldOdds: string) => {
  upDown.value = ''
  oldONum.value = ''

  if (+saveNum.value !== +newOdds) {
    oldONum.value = oldOdds
    upDown.value = +newOdds > +saveNum.value ? 'up' : 'down'

    resetOldNum()
    resetUpDown()
    saveNum.value = newOdds
  }

  // 向购物车发送
  listToCartData.value.ov = newOdds
  listToCartEventEmit()
})

watch(() => props.disabled, (val) => {
  _disabled.value = val
  listToCartData.value.os = val ? 0 : 1
  listToCartEventEmit()
})

onMounted(() => {
  addCartToListEvent()
})
onBeforeUnmount(() => {
  removeCartToListEvent()
})
</script>

<template>
  <div ref="betButton" :class="[size]" class="sports-bet-button" style="--odds-duration: 0.35s;">
    <div class="layer1"
      :class="[size, { 'is-selected': sportsStore.cart.checkWid(props.cartInfo.wid), disabled: _disabled }]"
      @click="clickHandler">
      <div class="w-full h-full top-0 left-0 absolute">
        <span :class="`odd-${upDown}`" />
      </div>
      <div class="name">
        <span>{{ title }}</span>
      </div>
      <div class="odds">
        <!-- 跌📉 -->
        <span v-if="oldONum && upDown === 'down'" class="move-up odd-span"
          v-html="sportsStore.renderOdds(+oldONum).value" />
        <span :class="[`move-${direction} odd-span`]" v-html="sportsStore.renderOdds(+odds).value" />
        <!-- 涨📈 -->
        <span v-if="oldONum && upDown === 'up'" class="move-down odd-span"
          v-html="sportsStore.renderOdds(+oldONum).value" />
      </div>
    </div>
  </div>
</template>

<style lang='scss' scoped>
.sports-bet-button {
  width: 100%;
  height: 40px;

  &.small {
    padding: 4px;
  }

  .layer1 {
    color: var(--color-text-white-0);
    background-color: var(--color-bg-black-5);
    border: solid 1px;
    border-color: var(--color-bg-black-5);
    transition: 0.2s ease-in-out;
    cursor: pointer;
    display: flex;
    padding: 0 8px;
    position: relative;
    line-height: 30px;
    justify-content: center;
    border-radius: 8px;
    font-weight: 600;
    height: 100%;

    &.disabled {
      color: var(--color-text-white-0);
      cursor: default;
      opacity: 0.3;
      background: var(var(--color-bg-black-5));
      transition: color 0.1s ease-in-out;
      border-color: var(var(--color-bg-black-5));
      pointer-events: none;
      user-select: none;
    }

    &.small {
      height: 32px;
    }

    @media (hover: hover) and (pointer: fine) {
      &:hover {
        color: var(--color-text-white-0);
        background: var(--color-black-50);
        border-color: var(--color-black-50);
      }
    }

    &.is-selected {
      .name {
        opacity: 1;
        color: #232626;
      }

      color: rgb(35, 38, 38);
      background: rgb(36, 238, 137);
      border-color: rgb(36, 238, 137);

      &:hover {
        color: rgb(35, 38, 38);
        background: rgba(36, 238, 137, 0.75);
        border-color: rgba(36, 238, 137, 0.75);
      }
    }

    .name {
      flex: 1 1 0%;
      color: var(--color-white-500);
      display: flex;
      font-size: 12px;
      mask-image: linear-gradient(90deg, rgb(0, 0, 0) 80%, rgba(0, 0, 0, 0) 100%);
      transition: color 0.1s ease-in-out;
      align-items: center;
      line-height: 1.2;
      padding-inline-end: 4px;

      span {
        height: 1.2em;
        overflow: hidden;
        box-sizing: border-box;
        word-break: break-all;
      }
    }

    .odds {
      flex: none;
      display: flex;
      flex-direction: column;
      height: 1.2em;
      line-height: 1.2;
      font-size: 12px;
      overflow: hidden;
      align-self: center;
      text-align: right;

      .odd-span {
        display: block;
        height: 1.2em;
        line-height: 1.2;
        font-size: 12px;
      }
    }
  }
}

// 跌，赔率往上
.move-up {
  animation-name: oddGoDownSpanMoveUp;
  animation-duration: 0.35s;
}

@keyframes oddGoDownSpanMoveUp {
  from {
    transform: translateY(0);
  }

  to {
    transform: translateY(-100%);
  }
}

// 涨，赔率往下
.move-down {
  animation-name: oddGoUpSpanMoveDown;
  animation-duration: 0.35s;
}

@keyframes oddGoUpSpanMoveDown {
  from {
    transform: translateY(-100%);
  }

  to {
    transform: translateY(0);
  }
}

.odd-up {
  top: 2px;
  right: 2px;
  width: 0;
  height: 0;
  position: absolute;
  border-color: transparent #24ee89 transparent transparent;
  border-style: solid;
  border-width: 0 8px 8px 0;
  animation-name: Ani-odd-changed;
  animation-duration: 2s;
}

.odd-down {
  right: 2px;
  width: 0;
  bottom: 2px;
  height: 0;
  position: absolute;
  border-color: transparent transparent #fc3c3c transparent;
  border-style: solid;
  border-width: 0 0 8px 8px;
  animation-name: Ani-odd-changed;
  animation-duration: 2s;
}

@keyframes Ani-odd-changed {
  16% {
    opacity: 1;
  }

  32% {
    opacity: 0;
  }

  48% {
    opacity: 1;
  }

  64% {
    opacity: 0;
  }

  80% {
    opacity: 1;
  }

  100% {
    opacity: 0;
  }
}
</style>
